<script lang="ts" setup>
import {
  IconImageAddLine,
  IconDeleteBin,
  IconSave,
  VButton,
  VModal,
  VSpace,
  VTag,
  VAvatar,
  VCard,
  Toast,
} from "@halo-dev/components";
import { FormKit } from "@formkit/vue";
import { computed, nextTick, ref, watch } from "vue";
import type { Product, ProductType } from "@console/types";
import { productApiClient, productTypeApiClient } from "@console/api/product";
import { cloneDeep } from "lodash-es";
import { setFocus } from "@console/formkit/utils/focus";
import { submitForm } from "@console/formkit/utils/submit";

const props = withDefaults(
  defineProps<{
    visible: boolean;
    product?: Product;
  }>(),
  {
    visible: false,
    product: undefined,
  }
);

const emit = defineEmits<{
  "update:visible": [visible: boolean];
  "close": [];
}>();

const initialFormState: Product = {
  spec: {
    displayName: "",
    productTypeRef: "",
    description: "",
    images: [],
    price: undefined,
    samplePrice: undefined,
    minOrderQuantity: undefined,
    priority: 0,
    published: true,
  },
  apiVersion: "content.halo.run/v1alpha1",
  kind: "Product",
  metadata: {
    name: "",
    generateName: "product-",
  },
};

const formState = ref<Product>(cloneDeep(initialFormState));
const productTypes = ref<ProductType[]>([]);
const saving = ref(false);
const formVisible = ref(false);
const uploading = ref(false);
const fileInput = ref<HTMLInputElement>();

const isUpdateMode = computed(() => {
  return !!formState.value.metadata.creationTimestamp;
});

const modalTitle = computed(() => {
  return isUpdateMode.value ? "编辑产品" : "新建产品";
});

const productTypeOptions = computed(() => {
  return productTypes.value.map((type) => ({
    label: type.spec.displayName,
    value: type.metadata.name,
  }));
});

// computed值用于处理string/number转换
const priceStr = computed({
  get: () => {
    const price = formState.value.spec.price;
    return price !== null && price !== undefined ? String(price) : '';
  },
  set: (value: string) => {
    formState.value.spec.price = value ? parseFloat(value) || 0 : 0;
  }
});

const samplePriceStr = computed({
  get: () => {
    const price = formState.value.spec.samplePrice;
    return price !== null && price !== undefined ? String(price) : '';
  },
  set: (value: string) => {
    formState.value.spec.samplePrice = value ? parseFloat(value) || 0 : 0;
  }
});

const minOrderQuantityStr = computed({
  get: () => {
    const quantity = formState.value.spec.minOrderQuantity;
    return quantity !== null && quantity !== undefined ? String(quantity) : '';
  },
  set: (value: string) => {
    formState.value.spec.minOrderQuantity = value ? parseInt(value, 10) || 1 : 1;
  }
});

const priorityStr = computed({
  get: () => {
    const priority = formState.value.spec.priority;
    return priority !== null && priority !== undefined ? String(priority) : '';
  },
  set: (value: string) => {
    formState.value.spec.priority = value ? parseInt(value, 10) || 0 : 0;
  }
});

// 字段名称映射
const fieldNameMap = {
  'spec.displayName': '产品名称',
  'spec.productTypeRef': '产品类型',
  'spec.description': '产品描述',
  'spec.price': '单价',
  'spec.samplePrice': '样品价格',
  'spec.minOrderQuantity': '最低起订量',
  'spec.priority': '优先级',
  'metadata.name': '别名',
};

// 解析验证错误信息
const parseValidationError = (error: any): string => {
  if (!error?.response?.data?.detail) {
    return '保存失败，请检查输入信息';
  }

  const detail = error.response.data.detail;
  const validationErrors: string[] = [];

  // 匹配验证错误模式
  const errorPattern = /spec\.(\w+):\s*(.+?)\s*\(code:/g;
  let match;

  while ((match = errorPattern.exec(detail)) !== null) {
    const fieldPath = `spec.${match[1]}`;
    const errorMessage = match[2];
    const fieldName = fieldNameMap[fieldPath] || fieldPath;

    if (errorMessage.includes('Min length')) {
      validationErrors.push(`${fieldName}不能为空`);
    } else if (errorMessage.includes('required')) {
      validationErrors.push(`${fieldName}是必填项`);
    } else if (errorMessage.includes('Max length')) {
      validationErrors.push(`${fieldName}长度超出限制`);
    } else if (errorMessage.includes('Invalid value')) {
      validationErrors.push(`${fieldName}格式不正确`);
    } else {
      validationErrors.push(`${fieldName}: ${errorMessage}`);
    }
  }

  if (validationErrors.length > 0) {
    return validationErrors.join('；');
  }

  return '保存失败，请检查输入信息';
};

const handleVisibleChange = (visible: boolean) => {
  emit("update:visible", visible);
  if (!visible) {
    emit("close");
  }
};

const handleFetchProductTypes = async () => {
  try {
    const { data } = await productTypeApiClient.listProductTypes({
      page: 0,
      size: 0,
    });
    productTypes.value = data.items;
  } catch (error) {
    console.error("Failed to fetch product types", error);
  }
};

const handleImageUpload = async (file: File) => {
  try {
    uploading.value = true;
    
    // 创建FormData上传文件
    const formData = new FormData();
    formData.append('file', file);
    formData.append('policyName', 'default-policy');
    
    // 调用控制台附件上传API
    const response = await fetch('/apis/api.console.halo.run/v1alpha1/attachments/upload', {
      method: 'POST',
      body: formData,
      credentials: 'include'
    });
    
    if (!response.ok) {
      throw new Error(`上传失败: ${response.status} ${response.statusText}`);
    }
    
    const result = await response.json();
    
    // 获取上传后的永久链接
    let imageUrl: string | undefined;
    if (result.status?.permalink) {
      imageUrl = result.status.permalink;
    } else if (result.spec?.displayName) {
      imageUrl = `/upload/${result.spec.displayName}`;
    }
    
    if (!imageUrl) {
      throw new Error('服务器返回的数据中没有找到图片URL');
    }
    
    // 添加到表单数据
    if (!formState.value.spec.images) {
      formState.value.spec.images = [];
    }
    formState.value.spec.images.push(imageUrl);
    
    Toast.success("图片上传成功，已保存到服务器");
  } catch (error) {
    console.error("Failed to upload image", error);
    Toast.error("图片上传失败: " + (error as Error).message);
  } finally {
    uploading.value = false;
  }
};

const handleRemoveImage = (index: number) => {
  if (formState.value.spec.images) {
    formState.value.spec.images.splice(index, 1);
  }
};

const handleSubmit = async () => {
  try {
    saving.value = true;

    // 基本验证
    if (!formState.value.spec.displayName?.trim()) {
      Toast.error("请输入产品名称");
      return;
    }

    if (!formState.value.spec.productTypeRef?.trim()) {
      Toast.error("请选择产品类型");
      return;
    }

    if (isUpdateMode.value) {
      await productApiClient.updateProduct({
        name: formState.value.metadata.name,
        product: formState.value,
      });
    } else {
      // Generate name from displayName if not provided
      if (!formState.value.metadata.name) {
        const displayName = formState.value.spec.displayName;
        const name = displayName
          .toLowerCase()
          .replace(/[^a-z0-9\u4e00-\u9fa5]/g, "-")
          .replace(/-+/g, "-")
          .replace(/^-|-$/g, "");
        formState.value.metadata.name = name || formState.value.metadata.generateName || 'product-';
      }
      
      await productApiClient.createProduct({
        product: formState.value,
      });
    }

    Toast.success("保存成功");
    handleVisibleChange(false);
  } catch (error) {
    console.error("Failed to save product", error);
    
    // 解析并显示友好的错误信息
    const friendlyMessage = parseValidationError(error);
    Toast.error(friendlyMessage);
  } finally {
    saving.value = false;
  }
};

const handleResetForm = () => {
  formState.value = cloneDeep(initialFormState);
};

watch(
  () => props.visible,
  (visible) => {
    if (visible) {
      formVisible.value = true;
      handleFetchProductTypes();
    } else {
      setTimeout(() => {
        formVisible.value = false;
        handleResetForm();
      }, 200);
    }
  }
);

watch(
  () => props.product,
  (product) => {
    if (product) {
      formState.value = cloneDeep(product);
    } else {
      handleResetForm();
    }
  }
);

watch(
  () => formVisible.value,
  (visible) => {
    if (visible) {
      nextTick(() => {
        setFocus("displayNameInput");
      });
    }
  }
);
</script>

<template>
  <VModal
    :visible="visible"
    :width="800"
    :title="modalTitle"
    :centered="false"
    @update:visible="handleVisibleChange"
  >
    <template #actions>
      <VSpace>
        <VButton
          :loading="saving"
          type="primary"
          @click="submitForm('product-form', handleSubmit)"
        >
          <template #icon>
            <IconSave class="h-4 w-4" />
          </template>
          保存
        </VButton>
      </VSpace>
    </template>

    <FormKit
      v-if="formVisible"
      id="product-form"
      v-model="formState.spec"
      name="product-form"
      :actions="false"
      type="form"
      :config="{ validationVisibility: 'submit' }"
      @submit="handleSubmit"
    >
      <!-- 基本信息 -->
      <FormKit
        id="displayNameInput"
        v-model="formState.spec.displayName"
        :label="'产品名称'"
        type="text"
        name="displayName"
        validation="required|length:1,100"
      ></FormKit>
      
      <FormKit
        v-model="formState.spec.productTypeRef"
        :label="'产品类型'"
        type="select"
        name="productTypeRef"
        :options="productTypeOptions"
        validation="required"
        placeholder="请选择产品类型"
      ></FormKit>
      
      <FormKit
        v-model="formState.spec.description"
        :label="'产品描述'"
        type="textarea"
        name="description"
        :rows="5"
        validation="length:0,1000"
      ></FormKit>

      <!-- 产品图片 -->
      <div class="space-y-4 mt-6">
        <div>
          <label class="block text-sm font-medium text-gray-700 mb-2">
            产品图片
          </label>
          <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
            <div
              v-for="(image, index) in formState.spec.images"
              :key="index"
              class="relative group"
            >
              <VCard class="p-2">
                <VAvatar
                  :src="image"
                  :alt="`产品图片 ${index + 1}`"
                  size="lg"
                  class="w-full h-24 object-cover"
                />
                <VButton
                  type="danger"
                  size="sm"
                  class="absolute top-1 right-1 opacity-0 group-hover:opacity-100 transition-opacity"
                  @click="handleRemoveImage(index)"
                >
                  <template #icon>
                    <IconDeleteBin class="h-3 w-3" />
                  </template>
                </VButton>
              </VCard>
            </div>
            <div class="flex items-center justify-center">
              <div class="relative">
                <VButton
                  :loading="uploading"
                  type="secondary"
                  class="h-24 w-full border-dashed"
                  @click="() => fileInput?.click()"
                >
                  <template #icon>
                    <IconImageAddLine class="h-6 w-6" />
                  </template>
                  上传图片
                </VButton>
                <input
                  ref="fileInput"
                  type="file"
                  accept="image/*"
                  class="hidden"
                  @change="(e) => {
                    const target = e.target as HTMLInputElement;
                    const file = target && target.files && target.files[0];
                    if (file) handleImageUpload(file);
                  }"
                />
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 价格信息 -->
      <div class="mt-6">
        <h3 class="text-sm font-medium text-gray-700 mb-4">价格信息</h3>
        <FormKit
          v-model="priceStr"
          :label="'单价（元）'"
          type="text"
          name="price"
          validation="number|min:0"
        ></FormKit>
        
        <FormKit
          v-model="samplePriceStr"
          :label="'样品价格（元）'"
          type="text"
          name="samplePrice"
          validation="number|min:0"
        ></FormKit>
        
        <FormKit
          v-model="minOrderQuantityStr"
          :label="'最低起订量'"
          type="text"
          name="minOrderQuantity"
          validation="number|min:1"
        ></FormKit>
      </div>

      <!-- 高级设置 -->
      <div class="mt-6">
        <h3 class="text-sm font-medium text-gray-700 mb-4">高级设置</h3>
        <FormKit
          v-model="formState.spec.published"
          :label="'发布状态'"
          type="checkbox"
          name="published"
          :help="'是否在前台显示该产品'"
        ></FormKit>
        
        <FormKit
          v-model="priorityStr"
          :label="'优先级'"
          type="text"
          name="priority"
          :help="'数值越大优先级越高'"
          validation="number|min:0"
        ></FormKit>
        
        <FormKit
          v-if="isUpdateMode"
          v-model="formState.metadata.name"
          :label="'别名'"
          type="text"
          name="name"
          validation="required|length:1,63"
          :help="'用于标识产品的唯一名称，创建后不可修改'"
          :disabled="true"
        ></FormKit>
      </div>
    </FormKit>
  </VModal>
</template>